package com.ruoyi.system.api.service.impl;

import java.util.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.api.ResponseWithData;
import com.ruoyi.system.api.domain.*;
import com.ruoyi.system.api.mapper.AnnexMapper;
import com.ruoyi.system.api.mapper.ReportInfoMapper;
import com.ruoyi.system.api.mapper.StReportPortMapper;
import com.ruoyi.system.api.service.CcService;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.api.mapper.StErrorReportMapper;
import com.ruoyi.system.api.service.IStErrorReportService;
import com.ruoyi.common.core.text.Convert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

/**
 * error reportService业务层处理
 *
 * @author ruoyi
 * @date 2020-03-05
 */
@Service
public class StErrorReportServiceImpl implements IStErrorReportService {
    private static final Logger log = LoggerFactory.getLogger(StErrorReportServiceImpl.class);

    @Autowired
    private StErrorReportMapper stErrorReportMapper;

    @Autowired
    private ReportInfoMapper reportInfoMapper;

    @Autowired
    private AnnexMapper annexMapper;

    /**
     * 报告与备件的关系表
     */
    @Autowired
    private StReportPortMapper reportPortMapper;

    /**
     * 调用CC接口service
     */
    @Autowired
    private CcService ccService;

    /**
     * 配置文件
     */
    @Autowired
    private Global global;

    /**
     * 查询error report
     *
     * @param id error reportID
     * @return error report
     */
    @Override
    public StErrorReport selectStErrorReportById(Long id) {
        return stErrorReportMapper.selectStErrorReportById(id);
    }

    /**
     * 查询error report列表
     *
     * @param stErrorReport error report
     * @return error report
     */
    @Override
    public List<StErrorReport> selectStErrorReportList(StErrorReport stErrorReport) {
        return stErrorReportMapper.selectStErrorReportList(stErrorReport);
    }

    /**
     * 新增error report
     *
     * @param stErrorReport error report
     * @return 结果
     */
    @Override
    public int insertStErrorReport(StErrorReport stErrorReport) {
        stErrorReport.setCreateTime(DateUtils.getNowDate());
        return stErrorReportMapper.insertStErrorReport(stErrorReport);
    }

    /**
     * 修改error report
     *
     * @param stErrorReport error report
     * @return 结果
     */
    @Override
    public int updateStErrorReport(StErrorReport stErrorReport) {
        stErrorReport.setUpdateTime(DateUtils.getNowDate());
        return stErrorReportMapper.updateStErrorReport(stErrorReport);
    }

    /**
     * 删除error report对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteStErrorReportByIds(String ids) {
        return stErrorReportMapper.deleteStErrorReportByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除error report信息
     *
     * @param id error reportID
     * @return 结果
     */
    @Override
    public int deleteStErrorReportById(Long id) {
        return stErrorReportMapper.deleteStErrorReportById(id);
    }

    /**
     * 添加ErrorReport报告
     *
     * @param errorReport
     * @return com.ruoyi.system.api.ResponseWithData<?>
     * @author yzg
     * @date 2020/3/5 1:27 下午
     */
    @Override
    public ResponseWithData<?> addErrorReport(StErrorReport errorReport) {
        if (errorReport.getPlanId() == null) {
            return new ResponseWithData<>().error("planId cannot be empty！");
        }
        if (errorReport.getNoticeId() == null) {
            return new ResponseWithData<>().error("noticeId cannot be empty！");
        }
        if (errorReport.getEnginnerId() == null) {
            return new ResponseWithData<>().error("enginnerId cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getServiceNo())) {
            return new ResponseWithData<>().error("serviceNo cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getEnCompanyName())) {
            return new ResponseWithData<>().error("enCompanyName cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getProblemStatement())) {
            return new ResponseWithData<>().error("problemStatement cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getRootCause())) {
            return new ResponseWithData<>().error("rootCause cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getCorrectiveActionTaken())) {
            return new ResponseWithData<>().error("correctiveActionTaken cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getTakenBy())) {
            return new ResponseWithData<>().error("takenBy cannot be empty！");
        }
        if (null == errorReport.getTrackDate()) {
            return new ResponseWithData<>().error("trackDate cannot be empty！");
        }

        // 1、保存Error Report报告信息
        if (errorReport.getId() == null) {

            errorReport.setCreateTime(new Date());
            errorReport.setCreateBy(errorReport.getEnginnerId() + "");
            errorReport.setDelFlag("0");
            errorReport.setSyncFlag("0");
            stErrorReportMapper.insertStErrorReport(errorReport);

            // Error Report信息保存到主表 st_report_info
            ReportInfo reportInfo = new ReportInfo();
            reportInfo.setServiceNo(errorReport.getServiceNo());
            reportInfo.setEnginnerId(errorReport.getEnginnerId());
            reportInfo.setPlanId(errorReport.getPlanId());
            reportInfo.setRelServiceNo(2L);
            reportInfo.setRelPlanId("st_error_report");
            reportInfo.setBatchType(errorReport.getId());
            reportInfo.setDelFlag("0");
            reportInfo.setCreateTime(new Date());
            reportInfo.setCreateBy(errorReport.getEnginnerId() + "");
            reportInfo.setNoticeId(errorReport.getNoticeId());
            reportInfo.setSyncFlag("0");
            reportInfo.setFseName(errorReport.getFseName());
            // TODO 报告编号生成规则是什么
            reportInfoMapper.insertStReportInfo(reportInfo);
        } else {
            errorReport.setUpdateTime(new Date());
            errorReport.setUpdateBy(errorReport.getEnginnerId() + "");
            stErrorReportMapper.updateStErrorReport(errorReport);
            ReportInfo reportInfo = reportInfoMapper.selectStReportInfoByBatchType(errorReport.getId(), "2");
            reportInfo.setUpdateBy(errorReport.getEnginnerId() + "");
            reportInfo.setUpdateTime(new Date());
            reportInfo.setEnginnerId(errorReport.getEnginnerId());
            reportInfo.setFseName(errorReport.getFseName());
            reportInfoMapper.updateStReportInfo(reportInfo);
        }


        // 2、更新图片附件关联信息
        Annex annex = new Annex();
        annex.setRelationId(errorReport.getId().toString());
        annex.setTblName("st_error_report");
        annex.setUpdateTime(new Date());
        annex.setServiceNo(errorReport.getServiceNo());
        annex.setHelpId(errorReport.getHelpId());
        annexMapper.updateAnnexByHelpIdAndServiceNo(annex);

        // 3、更新备件关联信息
        reportPortMapper.updatePhoneReportPortByHelpIdAndServiceNo(errorReport.getId(), errorReport.getHelpId(), errorReport.getServiceNo());


        return new ResponseWithData<>().success(errorReport).code(200);
    }

    /**
     * 修改ErrorReport报告
     *
     * @param errorReport
     * @return com.ruoyi.system.api.ResponseWithData<?>
     * @author yzg
     * @date 2020/3/5 1:28 下午
     */
    @Override
    public ResponseWithData<?> updateErrorReport(StErrorReport errorReport) {
        if (errorReport.getId() == null) {
            return new ResponseWithData<>().error("id cannot be empty！");
        }
        if (errorReport.getPlanId() == null) {
            return new ResponseWithData<>().error("planId cannot be empty！");
        }
        if (errorReport.getNoticeId() == null) {
            return new ResponseWithData<>().error("noticeId cannot be empty！");
        }
        if (errorReport.getEnginnerId() == null) {
            return new ResponseWithData<>().error("enginnerId cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getServiceNo())) {
            return new ResponseWithData<>().error("serviceNo cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getEnCompanyName())) {
            return new ResponseWithData<>().error("enCompanyName cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getProblemStatement())) {
            return new ResponseWithData<>().error("problemStatement cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getRootCause())) {
            return new ResponseWithData<>().error("rootCause cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getCorrectiveActionTaken())) {
            return new ResponseWithData<>().error("correctiveActionTaken cannot be empty！");
        }
        if (StringUtils.isEmpty(errorReport.getTakenBy())) {
            return new ResponseWithData<>().error("takenBy cannot be empty！");
        }
        if (null == errorReport.getTrackDate()) {
            return new ResponseWithData<>().error("trackDate cannot be empty！");
        }

        // 1、保存Error Report报告信息
        errorReport.setUpdateTime(new Date());
        errorReport.setUpdateBy(errorReport.getEnginnerId() + "");
        stErrorReportMapper.updateStErrorReport(errorReport);

        ReportInfo reportInfo = reportInfoMapper.selectStReportInfoByBatchType(errorReport.getId(), "2");
        reportInfo.setUpdateBy(errorReport.getEnginnerId() + "");
        reportInfo.setUpdateTime(new Date());
        reportInfo.setEnginnerId(errorReport.getEnginnerId());
        reportInfo.setFseName(errorReport.getFseName());
        reportInfoMapper.updateStReportInfo(reportInfo);

        // 2、更新图片附件关联信息
        Annex annex = new Annex();
        annex.setRelationId(errorReport.getId().toString());
        annex.setTblName("st_error_report");
        annex.setUpdateTime(new Date());
        annex.setServiceNo(errorReport.getServiceNo());
        annex.setHelpId(errorReport.getHelpId());
        annexMapper.updateAnnexByHelpIdAndServiceNo(annex);


        // 3、更新备件关联信息
        reportPortMapper.updatePhoneReportPortByHelpIdAndServiceNo(errorReport.getId(), errorReport.getHelpId(), errorReport.getServiceNo());

        return new ResponseWithData<>().success(errorReport).code(200);
    }

    /**
     * 查看ErrorReport报告
     *
     * @param id
     * @return com.ruoyi.system.api.ResponseWithData<?>
     * @author yzg
     * @date 2020/3/5 1:25 下午
     */
    @Override
    public ResponseWithData<?> detailErrorReport(Long id) {
        StErrorReport errorReport = stErrorReportMapper.selectStErrorReportById(id);
        if (errorReport != null) {
            ReportInfo reportInfo = reportInfoMapper.selectStReportInfoByBatchType(errorReport.getId(), "2");
            errorReport.setPlanId(reportInfo.getPlanId());
            errorReport.setNoticeId(reportInfo.getNoticeId());
            errorReport.setStatus(reportInfo.getStatus());
        }
        return new ResponseWithData<>().success(errorReport).code(200);
    }

    /**
     * 查看ErrorReport报告
     *
     * @param id
     * @return com.ruoyi.system.api.ResponseWithData<?>
     * @author yzg
     * @date 2020/3/5 1:25 下午
     */
    public ResponseWithData<?> detailCCErrorReport(Map map) {

        JSONObject jsonObject = ccService.getCCErrorReportDetail(map);
        return new ResponseWithData<>().success(jsonObject).code(200);
    }
    public static List<StReportPort> removeDupliById(List<StReportPort> persons) {
        Set<StReportPort> personSet = new TreeSet<>((o1, o2) -> o1.getPid().compareTo(o2.getPid()));
        personSet.addAll(persons);
        return new ArrayList<>(personSet);
    }
    /**
     * 提交Error report
     *
     * @param id
     * @return com.ruoyi.system.api.ResponseWithData<?>
     * @author yzg
     * @date 2020/3/7 11:26 上午
     */
    @Override
    public ResponseWithData<?> errorReportSubmit(Long id, Long enginnerId) {
        if (null == id) {
            return new ResponseWithData<>().error().msg("id cannot be empty");
        }
        if (null == enginnerId) {
            return new ResponseWithData<>().error().msg("enginnerId cannot be empty");
        }
        // 查寻Error Report基本信息
        StErrorReport stErrorReport = stErrorReportMapper.selectStErrorReportById(id);
        ReportInfo reportInfo = reportInfoMapper.selectStReportInfoByBatchType(id, "2");
        if (null == stErrorReport || null == reportInfo) {
            return new ResponseWithData<>().error().msg("Error report不存在");
        }
        if ("1".equals(reportInfo.getSyncFlag())) {
            return new ResponseWithData<>().error().msg("此Error report已提交过");
        }

        Map<String, Object> params = new HashMap<>();
        // 唯一主键
        params.put("report_guid", reportInfo.getId().toString());
        // Service号
        params.put("service_no", reportInfo.getServiceNo());
        // 提交的工程师ID
        params.put("enginner_id", enginnerId + "");
        // 用户英文名称
        params.put("customer_enname", stErrorReport.getEnCompanyName());
        // 错误发生日期
        params.put("error_time", DateUtils.parseDateToStrEmpty(DateUtils.YYYY_MM_DD_HH_MM_SS, stErrorReport.getErrorDate()));
        // 问题描述
        params.put("problem_statement", stErrorReport.getProblemStatement());
        // 原因
        params.put("root_cause", stErrorReport.getRootCause());
        // 补救措施
        params.put("corrective_action_taken", stErrorReport.getCorrectiveActionTaken());
        // 补救措施执行人
        params.put("taken_by", stErrorReport.getTakenBy());
        // 日期
        params.put("date", DateUtils.parseDateToStrEmpty(DateUtils.YYYY_MM_DD_HH_MM_SS, stErrorReport.getTrackDate()));


        Map<String, String> errorCodeData = new HashMap<>();
        // 一级代码
        errorCodeData.put("parent_code", stErrorReport.getParentCode());
        // 一级代码值
        errorCodeData.put("parent_value", stErrorReport.getParentValue());
        // 错误代码
        errorCodeData.put("err_code", stErrorReport.getErrCode());
        // 错误代码值
        if (StringUtils.isNotEmpty(stErrorReport.getErrValue())) {
            errorCodeData.put("err_value", stErrorReport.getErrValue().split(":")[1]);
        } else {
            errorCodeData.put("err_value", "");
        }
        // 描述
        errorCodeData.put("err_longdesc", stErrorReport.getErrLongdesc());

        // Error分类
        if (StringUtils.isNotEmpty(stErrorReport.getErrType())) {
            errorCodeData.put("Err_Type", stErrorReport.getErrType().split(":")[0]);
            // 责任人
            errorCodeData.put("err_responman", stErrorReport.getErrType().split(":")[1]);
        } else {
            errorCodeData.put("Err_Type", "");
            errorCodeData.put("err_responman", "");
        }

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(errorCodeData);
        params.put("error_code_data", jsonArray.toString());

        //附件图片
        List<Annex> annexes = annexMapper.selectAnnexByTblNameAndRelationId("st_error_report", stErrorReport.getId().toString());
        if (null != annexes) {
            List<Map<String, Object>> annexParams = new ArrayList<>();
            for (Annex annex : annexes) {
                JSONObject map = new JSONObject();
                map.put("Pic_Path",
                        //global.getPicUrl() +
                          annex.getFilePath());
                if (StringUtils.isEmpty(annex.getFileDescription())) {
                    map.put("Pic_Remark", "");
                } else {
                    map.put("Pic_Remark", annex.getFileDescription());
                }

                map.put("CREATE_TIME", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, annex.getCreateTime()));
                annexParams.add(map);
            }
            params.put("pic_list", annexParams);


        } else {
            params.put("pic_list", "[]");
        }
        List<Map<String, Object>> reportPortParams = new ArrayList<>();
        // 备件信息
        List<StReportPort> reportPorts = reportPortMapper.selectStReportPortListByServiceNoAndHelpIdAndPortType(stErrorReport.getServiceNo(), stErrorReport.getHelpId(), "3");
       // List<StReportPort> reportPorts = reportPortMapper.selectStReportPortListByReportIdAndPortType(stErrorReport.getId(), "3");
        //获取已提交的报告备件
        List<StReportPort> reportPortsSubmited = reportPortMapper.getSubmitServiceAndPhoneReportPorts(stErrorReport.getServiceNo());
       if(!ObjectUtils.isEmpty(reportPortsSubmited)){
           reportPortsSubmited = removeDupliById(reportPortsSubmited);
       }
        if (null != reportPorts) {
            if (null != reportPortsSubmited) {
                reportPorts.addAll(reportPortsSubmited);
            }
        } else {
            reportPorts = reportPortsSubmited;
        }
        if (null != reportPorts) {

            for (StReportPort reportPort : reportPorts) {
                JSONObject reportPortParam = new JSONObject();
                // 备件号
                reportPortParam.put("part_number", reportPort.getPartNumber());
                // 借贷单号
                reportPortParam.put("loan_number", StringUtils.isEmpty(reportPort.getLoanNumber()) ? "" : reportPort.getLoanNumber());
                // 备件序列号
                reportPortParam.put("part_serial_number", reportPort.getPartNumber());
                // 备件名称
                reportPortParam.put("part_name", reportPort.getPartName());
                //	QTY数量
                reportPortParam.put("qty_count", reportPort.getQtyCount());
                // Price单价
                reportPortParam.put("price", reportPort.getPrice());
                // Price总价
                reportPortParam.put("totalprice", reportPort.getTotalprice());
                // 更换类型
                reportPortParam.put("part_type", StringUtils.isEmpty(reportPort.getPartType()) ? "" : reportPort.getPartType());
                // 备注
                reportPortParam.put("remark", StringUtils.isEmpty(reportPort.getRemark()) ? "" : reportPort.getRemark());
                // 备件收货地址
                reportPortParam.put("Address", StringUtils.isEmpty(reportPort.getAddress()) ? "" : reportPort.getAddress());

                reportPortParams.add(reportPortParam);
            }
            params.put("part_data", reportPortParams);
        } else {
            params.put("part_data", "[]");
        }

        // 请求CC接口 提交电话解决报告
        String response = ccService.erroReporthandleerroReportInfo(params);

        /** 如果调用接口异常直接返回 */
        if (null == response) {
            return new ResponseWithData().error().msg("提交Error report失败 调用CC端提交Error report接口发生异常").code(202);
        }

        JSONObject jsonObject = JSONObject.parseObject(response);
        String status = jsonObject.getString("status");
        if ("1".equals(status)) {

            String rptNo = "";
            try {
                JSONArray record = jsonObject.getJSONArray("record");
                if (record != null && record.size() > 0) {
                    rptNo = record.getJSONObject(0).getString("rpt_no");
                }
            } catch (Exception e) {
                log.error("程序异常", e.getMessage());
            }
            // 提交成功 ，更新同步状态
            ReportInfo info = new ReportInfo();
            info.setId(reportInfo.getId());
            info.setSyncFlag("1");
            info.setSyncTime(new Date());
            info.setReportNo(rptNo);
            reportInfoMapper.updateStReportInfo(info);

            return new ResponseWithData().success().msg("提交Error report成功").code(200);
        } else if ("2".equals(status)) {
            String message = jsonObject.getString("message");
            return new ResponseWithData().error().msg(message).code(201);
        } else {
            return new ResponseWithData().error().msg("提交Error report失败 调用CC端提交Error report接口发生异常").code(201);
        }
    }

    @Override
    public List<ReportInfo> selectErrorReportList(String serviceNo, Long enginnerId, String planId) {
        return reportInfoMapper.selectStReportInfoByServiceNoAndRelServiceNo(serviceNo, "2");
    }

    @Override
    public ResponseWithData<?> delErrorReport(Long id, Long enginnerId) throws Exception {
        ReportInfo reportInfo = reportInfoMapper.selectStReportInfoById(id);
        if (null == reportInfo) {
            return new ResponseWithData<>().error().code(201).msg("报告不存在");
        }
        String syncFlag = reportInfo.getSyncFlag();
        if ("1".equals(syncFlag)) {
            String response = ccService.deleteServiceReport(enginnerId, reportInfo.getServiceNo(), reportInfo.getId() + "");

            /** 如果调用接口异常直接返回 */
            if (null == response) {
                return new ResponseWithData().error().msg("删除服务报告失败 调用CC端删除服务报告接口发生异常").code(202);
            }

            JSONObject jsonObject = JSONObject.parseObject(response);
            String status = jsonObject.getString("status");
            if ("1".equals(status)) {

                reportInfo.setUpdateTime(new Date());
                reportInfo.setUpdateBy(enginnerId + "");
                reportInfo.setDelFlag("2");
                reportInfoMapper.updateStReportInfo(reportInfo);

                return new ResponseWithData<>().success().code(200).msg("删除成功");
            } else if ("2".equals(status)) {
                String message = jsonObject.getString("message");
                return new ResponseWithData().error().msg(message).code(201);
            } else {
                return new ResponseWithData().error().msg("删除服务报告失败 调用CC端删除服务报告接口发生异常常").code(201);
            }
        } else {
            reportInfo.setUpdateTime(new Date());
            reportInfo.setUpdateBy(enginnerId + "");
            reportInfo.setDelFlag("2");
            reportInfoMapper.updateStReportInfo(reportInfo);
            return new ResponseWithData<>().success().code(200).msg("删除成功");
        }
    }

    @Override
    public List<ReportInfo> selectStErrorReportList(ReportInfo reportInfo) {
        return reportInfoMapper.selectStReportInfoList(reportInfo);
    }
}
